﻿using System;
using fastCSharp;
using fastCSharp.code.cSharp;

namespace diantou.web.ajax
{
    /// <summary>
    /// 企业考试
    /// </summary>
    [fastCSharp.code.cSharp.ajax(IsPool = true)]
    class exam : web.exam.view<exam>, webView.IWebView
    {
        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public void Register(diantou.examDataAccess.examUser value, Action<fastCSharp.net.returnValue<bool>> onReturn)
        {
            value.Id = user.Id;
            diantou.examDataAccess.tcpCall.examUser.register(value, onReturn);
        }
        /// <summary>
        /// 邀请用户注册
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public void GetInvitationMobileCode(long mobile, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            int id = web.pub.GetExamInvitationId(this);
            if (id == 0) onReturn(0);
            else diantou.examDataAccess.tcpCall.examInvitation.getMobileCode(mobile, id, onReturn);
        }
        /// <summary>
        /// 邀请用户注册
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public void RegisterInvitation(diantou.examDataAccess.examUser value, uint mobileCode, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            int id = web.pub.GetExamInvitationId(this);
            if (id == 0) onReturn(0);
            else
            {
                onRegisterReturn = onReturn;
                diantou.examDataAccess.tcpCall.examUser.registerInvitation(examUser = value, mobileCode, id, onRegister);
            }
        }
        /// <summary>
        /// 邀请用户注册回调
        /// </summary>
        private Action<fastCSharp.net.returnValue<int>> onRegisterReturn;
        /// <summary>
        /// 邀请用户注册回调
        /// </summary>
        /// <param name="returnValue"></param>
        private void onRegister(fastCSharp.net.returnValue<examDataAccess.examUser.registerResult> returnValue)
        {
            Action<fastCSharp.net.returnValue<int>> onReturn = onRegisterReturn;
            onRegisterReturn = null;
            if (returnValue.Type == fastCSharp.net.returnValue.type.Success)
            {
                if (returnValue.Value.Id == 0) onReturn(returnValue.Value.Return);
                else
                {
                    try
                    {
                        web.pub.ExamLogin(this, returnValue.Value.Id, returnValue.Value.Mobile);
                    }
                    finally { onReturn(1); }
                }
            }
            else onReturn(0);
        }
        /// <summary>
        /// 用户获取验证码(考生熟悉环境的测试赛/完成答卷后发简历的考试)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public void GetMobileCode(int examId, long mobile, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            diantou.examDataAccess.tcpCall.exam.getMobileCode(examId, mobile, onReturn);
        }
        /// <summary>
        /// 用户注册(考生熟悉环境的测试赛/完成答卷后发简历的考试)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public void RegisterExam(diantou.examDataAccess.examUser value, uint mobileCode, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            onRegisterReturn = onReturn;
            diantou.examDataAccess.tcpCall.examUser.register(value, mobileCode, onRegister);
        }
        /// <summary>
        /// 用户登录(考生熟悉环境的测试赛/完成答卷后发简历的考试)
        /// </summary>
        /// <returns></returns>
        public void LoginExam(int examId, long mobile, uint mobileCode, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            onRegisterReturn = onReturn;
            diantou.examDataAccess.tcpCall.examUser.login(examId, mobile, mobileCode, onRegister);
        }
        /// <summary>
        /// 找回验证码
        /// </summary>
        /// <param name="examId"></param>
        /// <param name="email"></param>
        /// <param name="onReturn"></param>
        public void SendMobileCodeToEmail(int examId, string email, Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            diantou.examDataAccess.tcpCall.examUser.getMobileCode(examId, email, onReturn);
        }
        /// <summary>
        /// 获取问题及其用户回答
        /// </summary>
        private static readonly fastCSharp.code.memberMap<dataModel.examQuestion> getQuestionAnswerMemberMap = fastCSharp.code.memberMap<dataModel.examQuestion>.CreateBuilder().Append(value => value.Id).Append(value => value.Type).Append(value => value.Description).Append(value => value.Answers).Append(value => value.Point);
        /// <summary>
        /// 获取问题及其用户回答
        /// </summary>
        /// <param name="id"></param>
        /// <param name="answer"></param>
        /// <returns></returns>
        public fastCSharp.emit.memberMapValue<dataModel.examQuestion> GetQuestionAnswer(int questionId, out diantou.dataModel.examAnswerBase answer)
        {
            if (user.IsRegister)
            {
                if (diantou.examDataAccess.tcpCall.examAnswer.getQuestion(user.Id, questionId))
                {
                    dataModel.examQuestion question = examDataAccess.clientCache.ExamQuestion[questionId];
                    answer = web.exam.problem.AnswerCacheClient.get(user.Id, question.Type, questionId);
                    return new fastCSharp.emit.memberMapValue<dataModel.examQuestion> { MemberMap = getQuestionAnswerMemberMap, Value = question };
                }
            }
            answer = null;
            return default(fastCSharp.emit.memberMapValue<dataModel.examQuestion>);
        }
        /// <summary>
        /// 获取题目及其用户回答
        /// </summary>
        private static readonly fastCSharp.code.memberMap<dataModel.problem> getProblemAnswerMemberMap = fastCSharp.code.memberMap<dataModel.problem>.CreateBuilder().Append(value => value.Id).Append(value => value.BasePoint).Append(value => value.Title).Append(value => value.Description).Append(value => value.InputDescription).Append(value => value.OutputDescription).Append(value => value.Input).Append(value => value.Output).Append(value => value.TimeLimit).Append(value => value.MemoryLimit);
        /// <summary>
        /// 获取题目及其用户回答
        /// </summary>
        /// <param name="problemId"></param>
        /// <param name="answer"></param>
        /// <returns></returns>
        public fastCSharp.emit.memberMapValue<dataModel.problem> GetProblemAnswer(int problemId, out diantou.dataModel.examAnswerBase answer)
        {
            if (user.IsRegister)
            {
                if (diantou.examDataAccess.tcpCall.examAnswer.getProblem(user.Id, problemId))
                {
                    dataModel.problem problem = examDataAccess.clientCache.ExamProblem[problemId].SourceProblem;
                    answer = web.exam.problem.AnswerCacheClient.get(user.Id, dataModel.examQuestionBase.type.Problem, problemId);
                    return new fastCSharp.emit.memberMapValue<dataModel.problem> { MemberMap = getProblemAnswerMemberMap, Value = problem };
                }
            }
            answer = null;
            return default(fastCSharp.emit.memberMapValue<dataModel.problem>);
        }
        /// <summary>
        /// 考试提交答卷
        /// </summary>
        /// <param name="sessionId"></param>
        public void Submit(Action<fastCSharp.net.returnValue<int>> onReturn)
        {
            if (user.IsRegister) diantou.examDataAccess.tcpCall.examUser.submit(user.Id, onReturn);
            else onReturn(0);
        }
        ///// <summary>
        ///// 用户考试日志与答案提交
        ///// </summary>
        ///// <param name="sessionId"></param>
        ///// <param name="times"></param>
        ///// <param name="types"></param>
        ///// <param name="indexs"></param>
        ///// <param name="contents"></param>
        ///// <param name="answers"></param>
        ///// <param name="questionIndex"></param>
        ///// <param name="isSubmit"></param>
        ///// <param name="onReturn"></param>
        //public void Log(int sessionId, uint[] times, byte[] types, short[] indexs, string[] contents, diantou.examDataAccess.examAnswer[] answers, int questionIndex, bool isSubmit, Action<fastCSharp.net.returnValue<int>> onReturn)
        //{
        //    if (user.IsRegister) diantou.dataAccess.tcpCall.examLog.append(user.Id, sessionId, times, types, indexs, contents, answers, questionIndex, isSubmit, onReturn);
        //    else onReturn(0);
        //}
        ///// <summary>
        ///// 添加考试编程日志
        ///// </summary>
        ///// <param name="sessionId"></param>
        ///// <param name="times"></param>
        ///// <param name="types"></param>
        ///// <param name="indexs"></param>
        ///// <param name="contents"></param>
        ///// <param name="answers"></param>
        ///// <param name="questionIndex"></param>
        ///// <param name="isSubmit"></param>
        ///// <param name="onReturn"></param>
        //public void JudgeLog(int sessionId, uint[] times, byte[] types, int[] startRows, int[] startColumns, int[] endRows, int[] endColumns, string[][] contents, bool isSubmit, Action<fastCSharp.net.returnValue<int>> onReturn)
        //{
        //    if (user.IsRegister) diantou.dataAccess.tcpCall.examJudgeLog.append(user.Id, sessionId, times, types, startRows, startColumns, endRows, endColumns, contents, isSubmit, onReturn);
        //    else onReturn(0);
        //}
        /// <summary>
        /// 考试编程提交
        /// </summary>
        /// <param name="value"></param>
        /// <param name="onReturn"></param>
        public void Judge(diantou.examDataAccess.examJudge value, bool isRun, Action<fastCSharp.net.returnValue<diantou.dataAccess.judgeClient.testJudge>> onReturn)
        {
            if (user.IsRegister)
            {
                value.UserId = user.Id;
                diantou.examDataAccess.tcpCall.examJudge.append(value, isRun, onReturn);
            }
            else onReturn(null);
        }
        /// <summary>
        /// 答案提交
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="answer"></param>
        /// <param name="questionIndex"></param>
        /// <param name="onReturn"></param>
        public void SetAnswer(int sessionId, diantou.examDataAccess.examAnswer answer, int questionIndex, Action<fastCSharp.net.returnValue<bool>> onReturn)
        {
            if (user.IsRegister) diantou.examDataAccess.tcpCall.examAnswer.set(user.Id, sessionId, answer, questionIndex, onReturn);
            else onReturn(false);
        }
        /// <summary>
        /// 答案提交
        /// </summary>
        /// <param name="sessionId"></param>
        /// <param name="answers"></param>
        /// <param name="questionIndex"></param>
        /// <param name="onReturn"></param>
        public void SetAnswers(int sessionId, diantou.examDataAccess.examAnswer[] answers, int questionIndex, Action<fastCSharp.net.returnValue<bool>> onReturn)
        {
            if (user.IsRegister) diantou.examDataAccess.tcpCall.examAnswer.set(user.Id, sessionId, answers, questionIndex, onReturn);
            else onReturn(false);
        }
        ///// <summary>
        ///// 上传头像图片
        ///// </summary>
        ///// <param name="sessionId"></param>
        //public void UploadImage(int sessionId)
        //{
        //    if (user.IsRegister && form.Files.Count != 0)
        //    {
        //        uploadTask.Add(uploadImage, new uploadUserImage { User = user, SessionId = sessionId, File = form.Files.GetRemoveAtEnd(0), WorkPath = WorkPath });
        //    }
        //}
        ///// <summary>
        ///// 上传头像图片
        ///// </summary>
        //private struct uploadUserImage
        //{
        //    /// <summary>
        //    /// 
        //    /// </summary>
        //    public string WorkPath;
        //    /// <summary>
        //    /// 
        //    /// </summary>
        //    public diantou.examDataAccess.examUser User;
        //    /// <summary>
        //    /// 
        //    /// </summary>
        //    public fastCSharp.net.tcp.http.requestForm.value File;
        //    /// <summary>
        //    /// 
        //    /// </summary>
        //    public int SessionId;
        //}
        ///// <summary>
        ///// 上传头像图片
        ///// </summary>
        ///// <param name="image"></param>
        //private void uploadImage(uploadUserImage image)
        //{
        //    string fileName = upload.LoadImage(image.WorkPath, image.File);
        //    if (fileName != null) diantou.examDataAccess.tcpCall.examUserImage.append(image.User.Id, image.SessionId, fileName.Substring(image.WorkPath.Length).replace('\\', '/'));
        //}
        /// <summary>
        /// 上传头像图片任务
        /// </summary>
        private static readonly fastCSharp.threading.task uploadTask = new fastCSharp.threading.task(4);
        /// <summary>
        /// 获取是否机器判题结束
        /// </summary>
        /// <returns></returns>
        [fastCSharp.code.cSharp.ajax(IsOnlyPost = false)]
        public bool CheckJudged()
        {
            return user.IsJudged;
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="sessionId"></param>
        /// <returns></returns>
        [fastCSharp.code.cSharp.ajax(IsOnlyPost = false)]
        public uint GetVerifyCode(int sessionId)
        {
            return user.IsRegister ? web.exam.problem.AnswerCacheClient.getVerifyCode(user.Id, sessionId).Value : 0;
        }
        /// <summary>
        /// 使用摄像头设置
        /// </summary>
        /// <param name="onReturn"></param>
        public void SetCamera(int sessionId, Action<fastCSharp.net.returnValue> onReturn)
        {
            diantou.examDataAccess.tcpCall.examUser.setCamera(user.Id, sessionId, onReturn);
        }
        /// <summary>
        /// 摄像头在线时间同步
        /// </summary>
        /// <param name="onReturn"></param>
        public void SetCameraTime(int sessionId, Action<fastCSharp.net.returnValue> onReturn)
        {
            diantou.examDataAccess.tcpCall.examUser.setCameraTime(user.Id, sessionId, onReturn);
        }
    }
}
